#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/ide.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/cdev.h>
#include <linux/device.h>

#define NEWCHRDEV_NAME	"newchardev"
#define NEWCHRDEV_CNT	1

struct newchrdev_st
{
	dev_t devID;
	struct cdev cdev;
	struct class *class;
	struct device *device;
	int major;
	int minor;
};

static ssize_t newchrdev_read(struct file *flip, char __user *buf, size_t cnt, loff_t *off_t)
{
//	flip->private_data = ;

	return 0;
}

static ssize_t newchrdev_write(struct file *flip, const char __user *buf, size_t cnt, loff_t *off_t)
{


	return 0;
}

static int newchrdev_open(struct inode *inode, struct file *flip)
{


	return 0;
}

static int newchrdev_release(struct inode *inode, struct file *flip)
{


	return 0;
}

static struct newchrdev_st newchrdev;

static struct file_operations newchardev_ops=
{
	.owner 		= THIS_MODULE,
	.read 		= newchrdev_read,
	.write 		= newchrdev_write,
	.open 		= newchrdev_open,
	.release 	= newchrdev_release,
};

static int __init newchrdevbase_init(void)
{
	int ret =0;
	//初始化寄存器、IO口等
	
	//申请设备号
	if(newchrdev.major)
	{
		newchrdev.devID = MKDEV(newchrdev.major, 0);
		ret = register_chrdev_region(newchrdev.devID, NEWCHRDEV_CNT, NEWCHRDEV_NAME);
		if(ret<0)
		{

		}
	}
	else
	{
		ret = alloc_chrdev_region(&newchrdev.devID, 0, NEWCHRDEV_CNT, NEWCHRDEV_NAME);
		if(ret<0)
		{

		}
		newchrdev.major = MAJOR(newchrdev.devID);
		newchrdev.minor = MINOR(newchrdev.devID);
	}

	//创建字符设备
	newchrdev.cdev.owner = THIS_MODULE;
	cdev_init(&newchrdev.cdev, &newchardev_ops);

	//添加字符设备
	ret = cdev_add(&newchrdev.cdev, newchrdev.devID, NEWCHRDEV_CNT);
	if(ret <0)
	{

	}

	//添加类
	newchrdev.class = class_create(THIS_MODULE, NEWCHRDEV_NAME);
	if(IS_ERR(newchrdev.class))
	{
		return PTR_ERR(newchrdev.class);
	}

	//注册设备
	newchrdev.device = device_create(newchrdev.class, NULL, newchrdev.devID, NULL, NEWCHRDEV_NAME);
	if(IS_ERR(newchrdev.device))
	{
		return PTR_ERR(newchrdev.device);
	}

	printk("newchrdev init sucess\r\n");

	return 0;
}

static void __exit newchrdevbase_exit(void)
{
	//注销设备号
	cdev_del(&newchrdev.cdev);
	unregister_chrdev_region(newchrdev.major, NEWCHRDEV_CNT);

	//卸载设备
	device_destroy(newchrdev.class , newchrdev.devID);
	class_destroy(newchrdev.class);

	printk("newchrdev exit sucess\r\n");
}

module_init(newchrdevbase_init);
module_exit(newchrdevbase_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("jtb");

